#ifndef __SERVER_NET_H__
#define __SERVER_NET_H__

#include <netinet/in.h>
#include <net/if.h>
#include <list>


using namespace std;

#define MAX_SENDBUF_SIZE (256 * 1024 * 1024)
#define MAX_RECVBUF_SIZE MAX_SENDBUF_SIZE
#define LIBNET_LIL_ENDIAN 1

/* used internally for checksum stuff */
#define LIBNET_CKSUM_CARRY(x) \
        (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff))

#define INTERFACE_MAX 10

enum INTERFACE_TYPE
{
    INTERFACE_TYPE_NONE = 0,
    INTERFACE_TYPE_LAN,
    INTERFACE_TYPE_WAN,
    INTERFACE_TYPE_ALL
};

typedef struct net_interface_tag
{
    int                 index;
    enum INTERFACE_TYPE type;
    char                address[INET_ADDRSTRLEN + 1];
    char                ifa_name[IFNAMSIZ + 1];
    int                 port;
    int                 sockfd;
    struct sockaddr_in  sockaddr;
    socklen_t           sockaddr_len;
} net_interface_t;


typedef struct sockaddr SA;

int setblock(int fd);
int setnonblock(int fd);
void maximize_sndbuf(const int sfd);
void maximize_rcvbuf(const int sfd);
int create_socket(const char* ip, int port, int type);
int send_udp_packet(int sockfd, 
                    SA* ssa, socklen_t ssalen, 
                    SA* dsa, socklen_t dsalen, 
                    void* payload, size_t payload_s, 
                    int flags);

list<net_interface_t*> net_interface_init(int port, int if_type, const char* specified_ip_list);
void net_interface_destroy(list<net_interface_t*>& if_list);

#endif
